package tms.business.login;

import sun.misc.BASE64Encoder;
import tms.model.login.UserEntity;
import tms.persistence.login.LoginProvider;
import tms.util.constants.UiMessage;
import tms.util.exception.ApplicationRuntimeException;
import tms.util.logging.Area;
import tms.util.logging.Logger;
import tms.util.security.AppSecurityManager;

import javax.ejb.EJB;
import javax.ejb.Local;
import javax.ejb.Stateless;
import javax.inject.Inject;
import javax.inject.Named;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.List;

import static tms.util.logging.AreaType.BUSINESS;

@Named
@Local
@Stateless
public class LoginService {
    @Inject @Area(BUSINESS)
    Logger logger;

    @Inject
    AppSecurityManager securityManager;
    @EJB
    LoginProvider loginProvider;

    public void createUser(String name, String password) {
        if (!loginProvider.getUsersByName(name).isEmpty()) {
            throw new ApplicationRuntimeException(UiMessage.USER_ALREADY_EXISTS);
        }
        UserEntity user = new UserEntity(name, buildHash(password));
        loginProvider.createUser(user);
    }

    public UserEntity login(String name, String password) {
        List<UserEntity> users = loginProvider.getUsersByName(name);
        if (!users.isEmpty()) {
            UserEntity user = users.get(0);
            if (!user.getPassword().equals(buildHash(password))) {
                throw new ApplicationRuntimeException(UiMessage.USER_OR_PASSWORD_INCORRECT);
            } else {
                return user;
            }
        } else {
            throw new ApplicationRuntimeException(UiMessage.USER_OR_PASSWORD_INCORRECT);
        }
    }

    public UserEntity findUser(Integer id) {
        return loginProvider.findUser(id);
    }

    /*
     *  Current realization uses SHA algorithm.
     */
    public String buildHash(String value) {
        String retVal = null;

        if (value != null) {
            MessageDigest md = null;
            try {
                md = MessageDigest.getInstance("SHA");
            } catch(NoSuchAlgorithmException e) {
                logger.warning("Error creating password hash.");
                throw new ApplicationRuntimeException(e.getCause());
            }
            try {
                md.update(value.getBytes("UTF-8"));
            } catch(UnsupportedEncodingException e) {
                logger.warning("Error creating password hash.");
                throw new ApplicationRuntimeException(e.getCause());
            }

            byte raw[] = md.digest();
            retVal = (new BASE64Encoder()).encode(raw);
        }

        return retVal;
    }

    public List<UserEntity> getAllUsers() {
        return loginProvider.getAllUsers();
    }
}
